function latexTableCell(fid,matCell,rowNames,colNames,format,tableTitle,cornerName,caption)
%% latexTableCell(fid,mat,rowNames,colNames,cornerName,caption)
% 
% This writes a Latex table from the cell matCell into an existing document using the 
% Longtable environment 
% 
% *Inputs* 
%
% 1. fid                  File identifier 
%
% 2. matCell:             [row col] cell
%
% 3. rowNames:            [row   1] optional cell with names of the rows 
%
% 4. colNames:            [col   1] optional cell with names of the columns 
%
% 5. *format* structure 
%
%   format.rows          [1 1] or [row 1] optional cell can be either empty,'\', or '$' 
%                                 
%   format.cols          [1 1] or [col 1] optional cell can be either empty,'\', or '$'
%                         will also apply to the titles, if provided 
%
%   format.landscape      optional=1 (default if undefined is zero) 
%                         Include *\usepackage{lscape}* in the preamble 
%
%   format.font           optional string 'scriptsize','small','tiny' default is none 
% 
% 6. tableTitle           optional string to put on top of the table 
%
% 7. cornerName:           [1     1] optional string to go on the left corner of the
%                          table 
%
% 8. caption:              [1     1] optional caption at the bottom of the table 
%
% *Example* 
%
% matCell=[dist num2cprec([lcone lctwo])]; 
% rowNames=parnames; 
% colNames={'Distribution','Mean','Standard Deviation'}; 
% format.rows='$'; 
% format.font=scriptsize; 
%
% latexTableCell(fid,matCell,rowNames,colNames,format,'Prior Posterior Table',....
% 'Parameters','Table 1'); 
% 
% Alejandro Justiniano (C) Sep 24 2013 


pos.tableTitle=6; 
pos.cornerName=7; 
pos.caption=8; 

% Flags that are turned on/off depending on input 
% flags.noRowNames 
% flags.noColNames 
% flags.landscape 
% flags.font 
% flags.rowFormat
% flags.colFormat 

%% 1. Flags for Format
% Dimensions
[Nrow,Ncol]=size(matCell); 
if nargin < 3
    flags.noRowNames=1;
else
    flags.noRowNames=isempty(rowNames);
end
if nargin < 4
    flags.noColNames=1;
else
    flags.noColNames=isempty(colNames);
end

% Landcape and Font 
flags.landscape=0; 
flags.font=0; 
if nargin > 4
    if ~isempty(format)
        if isfield(format,'landscape')==true && ~isempty(format.landscape)
            if format.landscape==1
                flags.landscape=1;
            end
        end
        if isfield(format,'font')==true && ~isempty(format.font)
            flags.font=1;
        end
    end
end
        
% Will rowNames and colNames be used and will be formated or not? 
% rowNames
flags.rowFormat=0;
if ~flags.noRowNames
    if length(rowNames)~=Nrow
        error('Wrong Dimension of Row Names');
    end
    if nargin > 4 && ~isempty(format) && isfield(format,'rows') && ~isempty(format.rows)
        if size( format.rows )==1 
            % Fill in with the single entry
            format.rows=fillcell(Nrow,1,char(format.rows));
        elseif size( format.rows )~=Nrow
            error('format.rows must match number of rows')
        end
        flags.rowFormat=1;
    end   
end

% colNames
flags.colFormat=0;
if ~flags.noColNames
    if length(colNames)~=Ncol
        error('Wrong Dimension Column Names');
    end
    if ~isempty(format) && isfield(format,'cols')  && ~isempty(format.cols)
        if size( format.cols )==1
            % Fill in with the single entry            
            format.rows=fillcell(Ncol,1,char(format.cols));
        elseif size( format.cols)~=Ncol
            error('format.cols must match number of columns')
        end
        flags.colFormat=0;
    end
end

% Strings that determine the formatting and corner 
% strinHeader for column names 
% stringTop   for column definition 
if nargin > (pos.cornerName-1) && isempty(cornerName)==false;
    stringHeader=char(cornerName);
else
    stringHeader='';
end
if ~flags.noRowNames
    stringTop='|l|';
else
    stringTop='|';
end
for ii=1:Ncol; 
    stringTop=strcat(stringTop,'c|');
    if ~flags.noColNames
        stringHeader=strcat(stringHeader,'&',char(colNames(ii)));
    end 
end 

%% 2. Begin Table and Headers
% 2.1 landscape and center 
if flags.landscape
    fprintf(fid,'\\begin{landscape} \n');
end
fprintf(fid,'\\begin{center} \n'); 

% 2.2 font 
if flags.font
    fprintf(fid,['\\',char(format.font),' \n']);
end

% 2.3 longtable 
fprintf(fid,['\\begin{longtable}{',stringTop,'} \n']); 

% 2.4 Table title
if nargin > (pos.tableTitle-1) && isempty(tableTitle)==false; 
    tempNcols=Ncol+1-flags.noRowNames; 
    fprintf(fid,['\\multicolumn{',num2str(tempNcols),'}{c}{',char(tableTitle),'}\\\\ \\hline \n']);     
end 

% 2.5 Column names 
if ~flags.noColNames
    fprintf(fid,[stringHeader, ' \\\\\\hline \\endhead \n']);
end

% 2.6 Footer for Longtable
fprintf(fid,'\\hline \\endfoot \n');

%% 3. Write rows of Matrix 
% Loop over each row.  Hence, each iteration is a different row.  We will
% build the row one column at a time.
for ii=1:Nrow; 
    
    
    % 3.1 Assign row names 
    % if there are row names passed through, then we will put that first.
    % Otherwise, we will leave it blank.
    % Beginning Format
    if flags.rowFormat && ~isempty(format.rows{ii})
        if ismember(format.rows{ii},{'$' '\'})
            fprintf(fid,'$');
        end
            
        if ismember(format.rows{ii},{'\'})
            fprintf(fid,'\\');
        end 
    end
    % Row Name
    if ~flags.noRowNames
        fprintf(fid,rowNames{ii});
    else
        fprintf(fid,'');
    end
    % Ending Format
    if flags.rowFormat && ~isempty(format.rows{ii})
        if ismember(format.rows{ii},{'$' '\'})
            fprintf(fid,'$');
        end
    end
    fprintf(fid,'&');
    
    % Now, loop over the remaining entries
    for jj=1:Ncol;
        % 3.2 Assign (i,j) entry
        % Beginning Format
        if flags.colFormat && ~isempty(format.cols{jj})
            if ismember(format.cols{jj},{'$' '\'})
                fprintf(fid,'$');
            end
            
            if ismember(format.cols{jj},{'\'})
                fprintf(fid,'\\');
            end
        end
        % Row Name
        if ~flags.noColNames
            if isnumeric(matCell{ii,jj})
                fprintf(fid,num2str(matCell{ii,jj}));
            else
                fprintf(fid,matCell{ii,jj});
            end
        else
            fprintf(fid,'');
        end
        % Ending Format
        if flags.colFormat && ~isempty(format.cols{jj})
            if ismember(format.cols{jj},{'$' '\'})
                fprintf(fid,'$');
            end
        end
        
        % 3.3 Append & to all but last column 
        if jj < Ncol
            fprintf(fid,'&');
        end  
    end
    
    % 3.4 Append \\hline to last row 
    if ii < Nrow
        fprintf(fid,'\\\\ \n');
    else
        fprintf(fid,'\\\\ \\hline \n');
    end
end

%% 4. Caption 
if nargin == pos.caption && ~isempty(caption)
    fprintf(fid,['\\caption{',caption,'} \n']);
end

%% 5. Close Table
fprintf(fid,'\\end{longtable} \n');
fprintf(fid,'\\end{center} \n');
if flags.landscape==1
    fprintf(fid,'\\end{landscape} \n');
end
fprintf(fid,'\n');
